﻿#region

using System;
using System.Collections.Generic;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

using Pob.CustomEventArgs;
using Pob.GameObjects;

#endregion

namespace Pob.ScreenManagement
{
    public class MenuScreen : Screens
    {
        #region Fields

        private readonly Background _background;

        private readonly List<DrawableGameComponent> _components = new List<DrawableGameComponent>();

        private readonly DrawString _exit;

        private readonly FpsCounter _fpsCounter;

        private readonly DrawString _options;

        private readonly DrawString _start;

        private int _debugCounter = 20;

        private Settings _settings = SettingsManager.CurrentInstance.Settings;

        private MainMenuStates _state;

        private double _timeLastKeyPressed;

        #endregion

        #region Constructors and Destructors

        public MenuScreen(Game game, EventHandler eventHandler)
        {
            _state = MainMenuStates.Start;
            _exit = new DrawString(
                game, 
                GameContent.FontMenuItems, 
                "Exit", 
                new Vector2(_settings.Width / 2, 200), 
                Color.White, 
                selected: false, 
                drawStringMode: DrawStringMode.WithSelected);
            _start = new DrawString(
                game, 
                GameContent.FontMenuItems, 
                "Start", 
                new Vector2(_settings.Width / 2, 100), 
                Color.White, 
                selected: true, 
                drawStringMode: DrawStringMode.WithSelected);
            _options = new DrawString(
                game, 
                GameContent.FontMenuItems, 
                "Options", 
                new Vector2(_settings.Width / 2, 150), 
                Color.White, 
                selected: false, 
                drawStringMode: DrawStringMode.WithSelected);
            _fpsCounter = new FpsCounter(game, GameContent.FontFpsCounter);
            _background = new Background(game, "background", new Vector2(0, 0), 1);

            MenuItemSelected += eventHandler;
        }

        #endregion

        #region Public Events

        public event EventHandler MenuItemSelected;

        #endregion

        #region Public Properties

        public MainMenuStates MainMenuState
        {
            get
            {
                return _state;
            }
        }

        #endregion

        #region Public Methods and Operators

        public override void Draw(GameTime gameTime)
        {
            foreach (var component in _components)
            {
                component.Draw(gameTime);
            }

            base.Draw(gameTime);
        }

        public override void LoadContent()
        {
            _components.Add(_background);
            _components.Add(_start);
            _components.Add(_options);
            _components.Add(_exit);

            if (_settings.FpsCounter)
            {
                _components.Add(_fpsCounter);
            }

            foreach (var component in _components)
            {
                component.Initialize();
            }
        }

        public override void UnloadContent()
        {
            foreach (var component in _components)
            {
                component.Dispose();
            }

            _components.Clear();
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            foreach (var component in _components)
            {
                component.Update(gameTime);
            }

            // Tastendruck wird sonst noch vom vorherigen Screen registriert
            // Debug only
            if (_debugCounter == 0)
            {
                Input(gameTime);
            }
            else
            {
                _debugCounter -= 1;
            }

            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
        }

        #endregion

        #region Methods

        protected virtual void OnSelectEntry()
        {
            if (MenuItemSelected != null)
            {
                MenuItemSelected(this, null);
            }
        }

        private void Input(GameTime gameTime)
        {
            KeyboardState key = Keyboard.GetState();

            if (gameTime.TotalGameTime.TotalSeconds - _timeLastKeyPressed > 0.15)
            {
                switch (MainMenuState)
                {
                    case MainMenuStates.Start:
                        {
                            if (key.IsKeyDown(Keys.Up))
                            {
                                SwitchSelectedMenuItem(_exit, _start, MainMenuStates.Exit, gameTime);
                            }

                            if (key.IsKeyDown(Keys.Down))
                            {
                                SwitchSelectedMenuItem(_options, _start, MainMenuStates.Options, gameTime);
                            }

                            if (key.IsKeyDown(Keys.Enter))
                            {
                                OnSelectEntry();
                            }

                            break;
                        }

                    case MainMenuStates.Options:
                        {
                            if (key.IsKeyDown(Keys.Down))
                            {
                                SwitchSelectedMenuItem(_exit, _options, MainMenuStates.Exit, gameTime);
                            }

                            if (key.IsKeyDown(Keys.Up))
                            {
                                SwitchSelectedMenuItem(_start, _options, MainMenuStates.Start, gameTime);
                            }

                            if (key.IsKeyDown(Keys.Enter))
                            {
                                OnSelectEntry();
                            }

                            break;
                        }

                    case MainMenuStates.Exit:
                        {
                            if (key.IsKeyDown(Keys.Up))
                            {
                                SwitchSelectedMenuItem(_options, _exit, MainMenuStates.Options, gameTime);
                            }

                            if (key.IsKeyDown(Keys.Down))
                            {
                                SwitchSelectedMenuItem(_start, _exit, MainMenuStates.Start, gameTime);
                            }

                            if (key.IsKeyDown(Keys.Enter))
                            {
                                OnSelectEntry();
                            }

                            break;
                        }
                }
            }
        }

        private void SwitchSelectedMenuItem(
            DrawString newItem, DrawString oldItem, MainMenuStates newState, GameTime time)
        {
            _state = newState;
            oldItem.Selected = false;
            oldItem.Scale = 1;
            newItem.Selected = true;

            _timeLastKeyPressed = time.TotalGameTime.TotalSeconds;
        }

        #endregion
    }
}